home *** CD-ROM | disk | FTP | other *** search
-
- {
- If anyone can fill me in on how to output in stereo, I'd be very
- appreciative... I've heard that port $220/$221 is for left channel,
- $222/$223 is for the right, but that doesn't make any sense...does it?
-
- This code makes R2D2 noises on a SoundBlaster until you press ESC.
-
- {adapted from SS4CH.PAS by Frank Hirsch}
- USES Crt;
-
- const sampleSize=4096;
- var sampleData:array[0..sampleSize-1]of byte;
- const samplePos:longint=0;
- var sampleSpeed:longint;
- var sampleDelta:longint;
-
- const resetPort =$226;
- const readPort =$22A;
- const writePort =$22C;
- const dataAvailPort=$22E;
-
- function readByte:byte;begin
- repeat until shortInt(port[dataAvailPort])<0;
- readByte:=port[readPort];
- end;
-
- procedure initDSP;begin
- port[resetPort]:=1;
- delay(1);
- port[resetPort]:=0;
- repeat until readByte=$AA;
- end;
-
- var counter:longint;
-
- procedure timerInt;assembler;asm
- push ax
- push bx
- push dx
- push di
- push ds
- push es
- mov ax,seg @DATA
- mov ds,ax
-
- mov es,[segB800]
- xor byte ptr es:[0],$21
-
- mov bx,[word ptr samplePos+2]
- mov ah,byte ptr sampleData[bx]
- mov dx,[word ptr sampleSpeed] {next sample byte}
- add [word ptr samplePos],dx
- adc bx,[word ptr sampleSpeed+2]
- and bx,[sampleSize-1]
- mov [word ptr samplePos+2],bx
- mov bx,[word ptr sampleDelta]
- add [word ptr sampleSpeed],bx
- mov bx,[word ptr sampleDelta+2]
- adc [word ptr sampleSpeed+2],bx
- mov dx,writePort
- @P2: {ready for output byte?}
- in al,dx
- test al,$80
- jnz @P2
- mov al,ah
- out dx,al
-
- mov al,$20 {process interrupt}
- out $20,al
- { sti}
- {prep NEXT output}
- @P1: {ready for command?}
- in al,dx
- test al,$80
- jnz @P1
- mov al,$10 {set up a DAC output}
- out dx,al
-
- db $66; inc word ptr [counter]
-
- pop es
- pop ds
- pop di
- pop dx
- pop bx
- pop ax
- iret
- end;
-
- var
- vec08:pointer absolute 0:8*4;
- old08:pointer;
-
- procedure setTimerTics(tics:word);begin
- asm cli; end;
- port[$43]:=$36;
- port[$40]:=lo(tics);
- port[$40]:=hi(tics);
- asm sti end;
- end;
-
- procedure setTimerFreq(freq:word);begin
- setTimerTics(succ(word($1234DC div freq)));
- end;
-
- procedure stopTimer;begin setTimerTics(0); end;
-
- procedure writeByte(b:byte);begin
- repeat until shortInt(port[writePort])>=0;
- port[writePort]:=b;
- end;
-
- procedure speaker(onOff:boolean);begin
- if onOff then writeByte($D1)
- else writeByte($D3);
- end;
-
- var i,j,n:word;
-
- const rate=16384;
-
- procedure note(freq,dur,slide:longint);
- begin
- counter:=0;
- sampleSpeed:=freq*sampleSize*(65536 div rate);
- sampleDelta:=slide;
- dur:=(dur*rate)div 1000;
- repeat
- if port[$60]=$81 then break;
- until counter>=dur;
- end;
-
-
- begin
- initDSP;
- for i:=0 to sampleSize-1 do
- sampleData[i]:=round(sin(i*pi/(sampleSize shr 1))*127.5+127.5);
- old08:=vec08;
- speaker(true);
- writeByte($10); {prep sb for data}
- asm cli end;
- vec08:=@timerInt;
- asm sti end;
- setTimerFreq(rate);
- repeat
- case random(4) of
- 0:note(random(1900)+60,(random(2)*80)+40,integer(random(3))-1);
- 1:note(random(800)+450,(random(2)*80)+140,integer(random(2049))
- -1024);
- 2:note(0,(random(2)+1)*40,0);
- 3:note(random(30)+15,(random(2)*80)+40,random(2));
- end;
- until port[$60]=$81;
- stopTimer;
- asm cli end;
- vec08:=old08;
- asm sti end;
- speaker(false); {it's probably gonna eat this as data}
- speaker(false);
- end.